package com.library.management.repository;

import com.library.management.entity.Book;
import com.library.management.entity.BookCategory;
import com.library.management.enums.BookStatus;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;

/**
 * 图书数据访问层接口
 * 提供图书相关的数据库操作
 *
 * @author 开发者
 * @version 1.0
 * @since 2025-10-20
 */
@Repository
public interface BookRepository extends JpaRepository<Book, Long> {

    // ========== 基础查询方法 ==========

    /**
     * 根据ISBN查找图书
     *
     * @param isbn ISBN号
     * @return 图书对象
     */
    Optional<Book> findByIsbn(String isbn);

    /**
     * 根据书名查找图书
     *
     * @param title 书名
     * @return 图书列表
     */
    List<Book> findByTitle(String title);

    /**
     * 根据作者查找图书
     *
     * @param author 作者
     * @return 图书列表
     */
    List<Book> findByAuthor(String author);

    /**
     * 根据出版社查找图书
     *
     * @param publisher 出版社
     * @return 图书列表
     */
    List<Book> findByPublisher(String publisher);

    /**
     * 检查ISBN是否存在
     *
     * @param isbn ISBN号
     * @return true-存在，false-不存在
     */
    boolean existsByIsbn(String isbn);

    // ========== 分类相关查询 ==========

    /**
     * 根据分类查找图书
     *
     * @param category 图书分类
     * @return 图书列表
     */
    List<Book> findByCategory(BookCategory category);

    /**
     * 根据分类ID查找图书
     *
     * @param categoryId 分类ID
     * @return 图书列表
     */
    List<Book> findByCategoryId(Long categoryId);

    /**
     * 根据分类和状态查找图书
     *
     * @param category 图书分类
     * @param status 图书状态
     * @return 图书列表
     */
    List<Book> findByCategoryAndStatus(BookCategory category, BookStatus status);

    // ========== 状态相关查询 ==========

    /**
     * 根据图书状态查找图书
     *
     * @param status 图书状态
     * @return 图书列表
     */
    List<Book> findByStatus(BookStatus status);

    /**
     * 查找可借阅的图书
     *
     * @return 可借阅图书列表
     */
    List<Book> findByStatusAndAvailableCopiesGreaterThan(BookStatus status, Integer availableCopies);

    /**
     * 统计指定状态的图书数量
     *
     * @param status 图书状态
     * @return 图书数量
     */
    long countByStatus(BookStatus status);

    // ========== 复杂查询方法 ==========

    /**
     * 根据书名模糊查询
     *
     * @param title 书名关键词
     * @return 图书列表
     */
    List<Book> findByTitleContainingIgnoreCase(String title);

    /**
     * 根据作者模糊查询
     *
     * @param author 作者关键词
     * @return 图书列表
     */
    List<Book> findByAuthorContainingIgnoreCase(String author);

    /**
     * 根据书名或作者模糊查询
     *
     * @param keyword 关键词
     * @return 图书列表
     */
    @Query("SELECT b FROM Book b WHERE b.title LIKE %:keyword% OR b.author LIKE %:keyword%")
    List<Book> findByTitleOrAuthorContaining(@Param("keyword") String keyword);

    /**
     * 根据出版年份范围查询
     *
     * @param startYear 开始年份
     * @param endYear 结束年份
     * @return 图书列表
     */
    List<Book> findByPublishYearBetween(Integer startYear, Integer endYear);

    /**
     * 根据价格范围查询
     *
     * @param minPrice 最低价格
     * @param maxPrice 最高价格
     * @return 图书列表
     */
    List<Book> findByPriceBetween(Double minPrice, Double maxPrice);

    // ========== 分页查询 ==========

    /**
     * 分页查询所有图书
     *
     * @param pageable 分页参数
     * @return 分页图书数据
     */
    Page<Book> findAll(Pageable pageable);

    /**
     * 根据状态分页查询图书
     *
     * @param status 图书状态
     * @param pageable 分页参数
     * @return 分页图书数据
     */
    Page<Book> findByStatus(BookStatus status, Pageable pageable);

    /**
     * 根据分类分页查询图书
     *
     * @param category 图书分类
     * @param pageable 分页参数
     * @return 分页图书数据
     */
    Page<Book> findByCategory(BookCategory category, Pageable pageable);

    // ========== 业务相关查询 ==========

    /**
     * 查找热门借阅图书（借阅次数最多的图书）
     *
     * @param limit 返回数量
     * @return 热门图书列表
     */
    @Query("SELECT b FROM Book b ORDER BY SIZE(b.borrowRecords) DESC")
    List<Book> findPopularBooks(@Param("limit") int limit);

    /**
     * 查找新入库的图书
     *
     * @param limit 返回数量
     * @return 新书列表
     */
    @Query("SELECT b FROM Book b ORDER BY b.createdTime DESC")
    List<Book> findNewBooks(@Param("limit") int limit);

    /**
     * 统计每个分类的图书数量
     */
    @Query("SELECT b.category, COUNT(b) FROM Book b GROUP BY b.category")
    List<Object[]> countBooksByCategory();

    /**
     * 全文搜索图书（需要数据库支持全文索引）
     */
    @Query(value = "SELECT * FROM books WHERE MATCH(title, author, publisher, summary) AGAINST (:keyword IN NATURAL LANGUAGE MODE)",
            nativeQuery = true)
    List<Book> fullTextSearch(@Param("keyword") String keyword);
}